﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Goods {
	string _name; //名字
	double _price; //价格
	int _evaluate; //评价
	Goods(const char* str, double price, int evaluate)
		:_name(str)
		, _price(price)
		, _evaluate(evaluate) {
	}
};

struct ComparePriceLess {
	bool operator()(const Goods& gl, const Goods& gr) { return gl._price < gr._price; }
};
struct ComparePriceGreater {
	bool operator()(const Goods& gl, const Goods& gr) { return gl._price > gr._price; }
};

//int main() {
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };
//	////sort无法直接排序，需要自定义仿函数(即比较规则)
//	//sort(v.begin(), v.end(), ComparePriceLess());
//	//sort(v.begin(), v.end(), ComparePriceGreater());
//	
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)->bool {return g1._price < g2._price; });
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._evaluate > g2._evaluate; });
//	return 0;
//}



////lambda表达式 基本使用
//int main() {
//	auto f1 = [](int x)->int {cout << x << endl; return 0; };
//	f1(1);
//	cout << typeid(f1).name() << endl;
//	//class <lambda_620c015845ff2142109bf3f80a50cb0a>
//	//每个lambda都是一个类，f1就是一个类对象
//	//f1对象可以调用operator()，所以lambda本质是仿函数
//
//	//省略返回类型，编译器自动推导
//	auto f2 = [](int x) {
//		cout << x << endl; 
//		return 0; 
//	};
//	f2(2);
//	cout << typeid(f2).name() << endl;
//	//class <lambda_5d21ffa5b2bbbd0b5a72ac1266224191>
//
//	ComparePriceGreater f3;
//	cout << typeid(f3).name() << endl;
//	//struct ComparePriceGreater
//	return 0;
//}



//lambda的其他用法
int main() {
	//使用lambda交换两个元素
	int x = 0, y = 1;
	cout << x << " " << y << endl;
	auto f1 = [](int& r1, int& r2) {
		int tmp = r1;
		r1 = r2;
		r2 = tmp;
	};
	f1(x, y);
	cout << x << " " << y << endl;


	cout << x << " " << y << endl;
	//[]可以捕获参数作为该类的成员变量，也就是仿函数的参数
	// ()中的参数默认是const修饰
	//所以加mutable可以取消其常量性
	//不需要参数传递()可以省略，但使用mutable参数列表不可省略
	//auto f2 = [x, y] () mutable { //交换失败，因为这是传值捕获
	//auto f2 = [&x, &y] () mutable { //修改为传引用捕获

	//mutable 的作用是允许 lambda 表达式修改 按值捕获的变量。
	//mutable 不影响引用捕获，因为 mutable 控制的是 lambda 对象本身的状态，
	//而引用捕获只是别名，修改的是外部变量。
	auto f2 = [&x, &y] { //可以省略() mutable
		int tmp = x;
		x = y;
		y = tmp;
	};
	f2();
	cout << x << " " << y << endl;

	return 0;
}



//[]捕获用法
class AA {
public:
	void func() {
		//捕获列表 [] 只能捕获 当前作用域内的局部变量 或 this 指针（对于成员函数），
		//而不能直接捕获 类的成员变量（如 _a1 和 _a2）。
		//在 AA::func() 内部，_a1 和 _a2 是 类的成员变量，而不是 局部变量。
		//C++ 的 lambda 捕获机制 只能捕获当前作用域内可见的变量（如局部变量、函数参数、全局变量等），
		//而成员变量必须通过 this 指针访问。
		//auto f1 = [_a1, _a2] {//不可行

		//auto f1 = [this] {
		auto f1 = [=] {
			cout << _a1 << endl;
			cout << _a2 << endl;
		};
		f1();
	}
private:
	int _a1;
	int _a2;
};

int main() {
	int x = 0, y = 1, z = 2;
	auto f1 = [=, &z] {
		z++;
		cout << x << endl;
		cout << y << endl;
		cout << z << endl;
	};
	f1();
	//捕获列表[]：用于 让 lambda 访问外部变量（相当于给 lambda 类添加了成员变量）。
	//参数列表()：用于 在调用 lambda 时传入临时参数（相当于函数参数）。
	//它们互相独立，捕获变量后仍然可以（或需要）参数列表，取决于你的需求。
	return 0;
}
